package cfca.paperless.client.servlet._1_basic._1_07_CompoundSealAutoPdfList;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import cfca.paperless.client.bean.ChannelBean;
import cfca.paperless.client.bean.MultiDataBean;
import cfca.paperless.client.bean.PdfBean;
import cfca.paperless.client.bean.SealUserInfo;
import cfca.paperless.client.bean.SignLocation;
import cfca.paperless.client.servlet.PaperlessClient;
import cfca.paperless.client.servlet.PaperlessConfig;
import cfca.paperless.client.util.Base64;
import cfca.paperless.client.util.GUID;
import cfca.paperless.client.util.IoUtil;
import cfca.paperless.client.util.PaperlessUtil;
import cfca.paperless.client.util.StrategyUtil;
import cfca.paperless.client.util.StringUtil;

public class CompoundSealAutoPdfListTest02 {

    public static void main(String[] args) throws Exception {
        long start = System.currentTimeMillis();
        try {
            PaperlessClient clientBean = new PaperlessClient(PaperlessConfig.url, 10000, 60000);

            ///////////////////////////如下为用户1的数据，如果没用用户1此处可以省略///////FileUtils.readFileToByteArray(new File(///////////////////////////////

            String pngFilePath = "./TestData/handwriting.png";
            
            String pngSuffix = IoUtil.getFileNameSuffix(pngFilePath);
            if(!PaperlessConfig.PNG_FILE_SUFFIX.equals(pngSuffix)){
                throw new Exception("所选文件不是png文件,签章图片文件只支持png格式图片");
            }
            String pngFileName1 = IoUtil.getFileName(pngFilePath);
            byte[] handwritingImage1 = FileUtils.readFileToByteArray(new File(pngFilePath));//加载手写签名图片
            byte[] handwritingData1 = handwritingImage1;//加载手写签名图片数据
            
            pngFilePath= "./TestData/1.png";
            pngSuffix = IoUtil.getFileNameSuffix(pngFilePath);
            if(!PaperlessConfig.PNG_FILE_SUFFIX.equals(pngSuffix)){
                throw new Exception("所选文件不是png文件,签章图片文件只支持png格式图片");
            }
            String pngFileName2 = IoUtil.getFileName(pngFilePath);
            byte[] identificationFrontData = FileUtils.readFileToByteArray(new File(pngFilePath));//加载场景照片
            
            pngFilePath= "./TestData/2.png";
            pngSuffix = IoUtil.getFileNameSuffix(pngFilePath);
            if(!PaperlessConfig.PNG_FILE_SUFFIX.equals(pngSuffix)){
                throw new Exception("所选文件不是png文件,签章图片文件只支持png格式图片");
            }
            String pngFileName3 = IoUtil.getFileName(pngFilePath);
            byte[] identificationBackData = FileUtils.readFileToByteArray(new File(pngFilePath));//加载场景照片

            List<MultiDataBean> list1 = new ArrayList<MultiDataBean>();
            list1.add(new MultiDataBean(handwritingData1, "handwritingData.dat", "descr1", "2"));
            
            list1.add(new MultiDataBean(handwritingImage1, pngFileName1, "2"));
            
            list1.add(new MultiDataBean(identificationFrontData, pngFileName2, "0"));
            
            list1.add(new MultiDataBean(identificationBackData, pngFileName3, "0"));

            List<SignLocation> signLocationList = new ArrayList<SignLocation>();
            signLocationList.add(new SignLocation(1, "代理人签名", "R", 10, 0));/// 表示在第一个pdf上的“交易柜员”关键字中间向上偏移50px后盖章

            String[] proofHashAndMultiData1 = PaperlessUtil.getProofHashAndMultiData(list1);

            SealUserInfo sealUserInfo = new SealUserInfo("张as", "Z", "ABC1DDD111", "14866659475", "beijing", "reason");//用户的信息，用来申请证书用
//            sealUserInfo.setKeyAlg("SM2");
            //产生证据策略文件并添加到clientBean中，此策略文件后台会申请场景证书用来盖章
            String proofSealStrategyXml1 = StrategyUtil.createProofSealStrategyXml(handwritingImage1, sealUserInfo, signLocationList, proofHashAndMultiData1[0]);
            ///////////////////////////以上为用户1的数据/////////////////////////////////////////////////
            
            ////--------------------------------------------------------------------------------------//////

            ///////////////////////////如下为用户2的数据，如果没用用户2此处也可以省略/////////////////////////////////////////////////
           
            pngFilePath = "./TestData/handwriting.png";
            
            pngSuffix = IoUtil.getFileNameSuffix(pngFilePath);
            if(!PaperlessConfig.PNG_FILE_SUFFIX.equals(pngSuffix)){
                throw new Exception("所选文件不是png文件,签章图片文件只支持png格式图片");
            }
             
            byte[] handwritingImage2 = FileUtils.readFileToByteArray(new File(pngFilePath));
            byte[] handwritingData2 = handwritingImage1;

            List<MultiDataBean> list2 = new ArrayList<MultiDataBean>();
            list2.add(new MultiDataBean(handwritingData2, "handwritingData.dat", "2"));
            list2.add(new MultiDataBean(handwritingImage2, "handwritingImage.png", "2"));

            List<SignLocation> signLocationList2 = new ArrayList<SignLocation>();
            signLocationList2.add(new SignLocation(1, "代理人签名", "R", 80, 0));

            String proofHashAndMultiData2 [] = PaperlessUtil.getProofHashAndMultiData(list2);

            sealUserInfo = new SealUserInfo("张三saaa", "Z", "ABC23Eds222", "15748465923", "beijing", "reason");
//            sealUserInfo.setKeyAlg("SM2");
            String proofSealStrategyXml2 = StrategyUtil.createProofSealStrategyXml(handwritingImage2, sealUserInfo, signLocationList2, proofHashAndMultiData2[0]);
            ///////////////////////////以上为用户2的数据/////////////////////////////////////////////////

            ///////////////////////////如下为加盖机构印章的策略/////////////////////////////////////////////////
            List<SignLocation> signLocationList3 = new ArrayList<SignLocation>();
            signLocationList3.add(new SignLocation(-1, "银行签章", "D", 20, 0));//加盖机构印章的位置，代表在第一个pdf文件中的“产品名称”的下方向上偏移50像素
            sealUserInfo = new SealUserInfo("机构", "北京", "签合同");//印章基本信息
            String sealCode = "org001";//印章编码，在后台印章管理里可以查询到该印章
            String sealPassword = "11111111";//印章密码
            //产生普通签章策略文件，并加到clientBean中，此策略文件后台会根据sealCode查找印章来盖章
            String businessCode = "";//业务码，用来显示在印章上，可以为空
            String businessCodeStyle = "font-size:19;x-ratio:0.1;y-ratio:0.3";//业务码样式,用来控制业务码显示字体大小和位置
            sealUserInfo.setBusinessCode(businessCode);
            sealUserInfo.setBusinessCodeStyle(businessCodeStyle);
            
            // 设置印章显示大小，可以不设置。比如：100，代表100px。比如需要把章显示为4cm（圆章且DPI为96）时，传入151即可。（并且imageScale配置为0.87）
            //sealUserInfo.setSealImageSize(100);
            
            String sealStrategyXml = StrategyUtil.createSealStrategyXml(sealCode, sealPassword, sealUserInfo, signLocationList3);
//            sealStrategyXml = StrategyUtil.createSealStrategyXml(sealCode, sealPassword, "章三十岁","", sealUserInfo, signLocationList3);

            //如下是pdf列表参数，<Pdf>里面的值可以是pdf文件的base64编码，也可以是pdf的磁盘的路径
            //<OutputFilePath>里面是pdf盖章后存放的地址，可以为空，如果不为空盖章后此pdf可以在单据稽核中查询到
            
            String pdfFilePath = "D:/TestData/wrong.pdf"; //"./TestData/file.pdf";
            String pdfSuffix = IoUtil.getFileNameSuffix(pdfFilePath);
            if(!PaperlessConfig.PDF_FILE_SUFFIX.equals(pdfSuffix)){
                throw new Exception("所选文件不是pdf文件");
            }
            String pdf1 = Base64.toBase64String(FileUtils.readFileToByteArray(new File(pdfFilePath)));
            
            String bizTypeCode = "001";
            List<PdfBean> pdfBeanList = new ArrayList<PdfBean>();
            String savedPdfId = GUID.generateId();
            String outputFilePath = "auto";
            pdfBeanList.add(new PdfBean(pdf1, savedPdfId, savedPdfId, bizTypeCode, outputFilePath, "12315468"));
            savedPdfId = GUID.generateId();
            pdfBeanList.add(new PdfBean(pdf1, savedPdfId, savedPdfId, bizTypeCode, outputFilePath, "12315468"));
            String pdfBeanListXml = PaperlessUtil.buildPdfBeanListXml(pdfBeanList);

            //调用自动化复合签章pdf列表方法
            String multiData = "[" + proofHashAndMultiData1[1] + "," + proofHashAndMultiData2[1] + "]";
            multiData = "";
            String compoundSealStrategyXml = "<List>" + proofSealStrategyXml1 + proofSealStrategyXml2 + sealStrategyXml + "</List>";
            String channelBeanXml = new ChannelBean(PaperlessConfig.channelCode).toString();
            
            // 获取场景证书的方式，与证据证书签章策略文件配合使用。默认值为0。0：实时从CFCA CA服务申请下载场景证书；1：使用从CFCA CA服务预先申请下载并存储在本地的场景证书；
            String sceneCertChannel = "0";
            
            // 获取时间戳的方式。默认值为0。0：实时访问CFCA 时间戳服务；1：使用从CFCA购置并在本地部署的时间戳服务器产品；
            String timestampChannel = "0";
            
            String sealedPdf = clientBean.compoundSealAutoPdfList(pdfBeanListXml, multiData, compoundSealStrategyXml, PaperlessConfig.operatorCode,
                    channelBeanXml, sceneCertChannel, timestampChannel);
//            String sealedPdf = clientBean.compoundSealAutoPdfListDetached(pdfBeanListXml, multiData, compoundSealStrategyXml, PaperlessConfig.operatorCode, channelBeanXml);
            String code = StringUtil.getNodeText(sealedPdf, "Code");
            //返回值Code等于200代表后台处理成功
            if (code.equals("200")) {
                List<String[]> list = getPdfBeanArr(sealedPdf);
                for (int i = 0; i < list.size(); i++) {
                    String[] strArr = list.get(i);
                    IoUtil.write("./TestData/output/compoundSealAutoPdfList-" + i + ".pdf", Base64.decode(strArr[0].getBytes()));
                    //System.out.println(strArr[1]);
                }

            } else {
                System.out.println(sealedPdf);
            }
            
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("time:" + (System.currentTimeMillis() - start));
    }

    private static List<String[]> getPdfBeanArr(String pdfs) {
        List<String[]> list = new ArrayList<String[]>();
        Object pdfArr[] = StringUtil.getXmlFieldArr(pdfs, "PdfBean");
        if (pdfArr != null && pdfArr.length > 0) {
            for (int i = 0; i < pdfArr.length; i++) {
                String pdfBeanString = "<PdfBean>" + pdfArr[i].toString() + "</PdfBean>";
                String pdf = StringUtil.getXmlField(pdfBeanString, "Pdf");
                String bizSerialNo = StringUtil.getXmlField(pdfBeanString, "BizSerialNo");
                if (StringUtil.isEmpty(bizSerialNo)) {
                    bizSerialNo = "";
                }
                list.add(new String[] { pdf, bizSerialNo });
            }
        }
        return list;
    }
}
